package org.szgb.console.sys.todo.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.szgb.console.sys.todo.entity.SysTodo;
import org.szgb.console.sys.todo.mapper.SysTodoMapper;
import org.szgb.console.sys.user.entity.SysUser;
import org.szgb.console.utils.Page;
import org.szgb.console.utils.UUIDUtil;
import org.szgb.console.wecom.robot.service.WeComRobotService;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class SysTodoService {
    private final SysTodoMapper sysTodoMapper;
    private final WeComRobotService weComRobotService;

    @Autowired
    public SysTodoService(SysTodoMapper sysTodoMapper, WeComRobotService weComRobotService) {
        this.sysTodoMapper = sysTodoMapper;
        this.weComRobotService = weComRobotService;
    }

    @Transactional(readOnly = true)
    public SysTodo get(String id) {
        return sysTodoMapper.get(id);
    }

    @Transactional(readOnly = true)
    public List<SysTodo> findList(SysTodo sysTodo) {
        if (sysTodo != null && sysTodo.getPageDto() != null) {
            Page<SysTodo> page = new Page<>(sysTodo.getPageDto());
            page.setFirst((page.getPageNo() - 1) * page.getPageSize());
            sysTodo.setPage(page);
        }
        return sysTodoMapper.findList(sysTodo);
    }

    @Transactional(readOnly = true)
    public Integer getCount(SysTodo sysTodo) {
        return sysTodoMapper.getCount(sysTodo);
    }

    @Transactional()
    public void save(SysTodo sysTodo) {
        // 检查实体对象的ID是否为null，判断是否为新实体
        if (sysTodo.getId() == null || sysTodo.getId().isEmpty()) {
            // 对于新实体，设置创建者信息
            sysTodo.setCreatedBy(sysTodo.getUpdatedBy());
            // 添加UUID
            sysTodo.setId(UUIDUtil.getUUID());
            // 执行插入操作
            sysTodoMapper.insert(sysTodo);
            // 返回成功插入的信息
        } else {
            // 执行更新操作
            sysTodoMapper.update(sysTodo);
        }
    }

    /**
     * 创建待办
     *
     * @param sign        待办标志
     * @param type        待办类型(1:单签,2:会签,3:抢签)
     * @param userIdArray 用户id数组
     * @param parameter   参数
     * @param title       标题
     * @param content     内容
     */
    @Transactional()
    public void createTodo(int sign, int type, String[] userIdArray, String parameter, String title, String content) {
        List<SysTodo> sysTodoList = new ArrayList<>();
        // 对于新实体，设置创建者信息
        String groudId = UUIDUtil.getUUID();
        Arrays.stream(userIdArray).forEach(userId -> {
            SysTodo sysTodo = new SysTodo();
            if (type != 1) {
                sysTodo.setGroupId(groudId);
            }
            sysTodo.setId(UUIDUtil.getUUID());
            sysTodo.setSign(sign);
            sysTodo.setType(type);
            sysTodo.setParameter(parameter);
            sysTodo.setTitle(title);
            sysTodo.setContent(content);
            sysTodo.setIsDeal(false);
            sysTodo.setUser(new SysUser(userId));
            sysTodo.setUpdatedBy(new SysUser("1"));
            sysTodo.setCreatedBy(sysTodo.getUpdatedBy());
            sysTodoList.add(sysTodo);
        });
        sysTodoMapper.insertBatch(sysTodoList);
    }

    // 在调用 createTodo 的地方改为异步执行
    @Async
    @Transactional
    public void asyncCreateTodo(int sign, int type, String[] userIds, String parameter, String title, String content) {
        try {
            this.createTodo(sign, type, userIds, parameter, title, content);
        } catch (Exception e) {
            // 记录异常日志，可考虑重试机制
            log.error("创建待办事项失败", e);
            // 可以实现重试逻辑
            retryCreateTodo(sign, type, userIds, parameter, title, content);
        }
    }

    private void retryCreateTodo(int sign, int type, String[] userIds, String parameter, String title, String content) {
        // 实现重试机制，比如延迟后重试
        CompletableFuture.delayedExecutor(5, TimeUnit.SECONDS)
                .execute(() -> {
                    try {
                        this.createTodo(sign, type, userIds, parameter, title, content);
                    } catch (Exception ex) {
                        log.error("重试创建待办事项失败", ex);
                    }
                });
    }

    @Transactional()
    public void createTodoAndRobotSend(int sign, int type, List<SysUser> sysUserList, String parameter, String title, String content) throws IOException, InterruptedException {
        weComRobotService.sendText(title + "   " + content, sysUserList.stream().map(SysUser::getUsername).toArray(String[]::new));
        this.createTodo(sign, type, sysUserList.stream().map(SysUser::getId).toArray(String[]::new), parameter, title, content);

    }

    /**
     * 审批
     *
     * @param parameter 参数
     * @return Boolean
     */
    @Transactional
    public Boolean approval(String parameter, String userId) {
        SysTodo sysTodo = sysTodoMapper.getByParameterWithUserId(parameter, userId);
        try {
            switch (sysTodo.getType()) {
                // 单签
                case 1:
                    sysTodoMapper.requiresById(sysTodo.getId());
                    return true;
                // 会签
                case 2:
                    sysTodoMapper.requiresById(sysTodo.getId());
                    SysTodo todo = new SysTodo();
                    todo.setGroupId(sysTodo.getGroupId());
                    todo.setIsDeal(false);
                    return sysTodoMapper.getCount(todo) == 0;
                // 抢签
                case 3:
                    sysTodoMapper.requiresByGroupId(sysTodo.getGroupId());
                    return true;
                default:
                    return false;
            }
        } catch (NullPointerException e) {
            log.error("知会处理异常{}{}", parameter, userId, e);
        }
        return false;
    }

    /**
     * 知会处理
     *
     * @param parameter parameter
     *
     */
    @Transactional
    public void approvalInform(String parameter, String userId) {
        SysTodo sysTodo = sysTodoMapper.getByParameterWithUserId(parameter, userId);
        sysTodoMapper.requiresById(sysTodo.getId());
    }


    @Transactional
    public void delete(String ids) {
        sysTodoMapper.delete(ids.split(","));
    }
}
